/*
 * ConversorDERaClases.cpp
 *
 *  Created on: May 27, 2013
 *      Author: root
 */

#include "conversion/ConversorDERaClases.h"
#include <vector>
#include "model/der/Attribute.h"
#include "model/der/Fork.h"
#include "gui/VisualComponents/der/VisualComponentForkVia.h"
#include "model/Diagram.h"
#include "model/Utils.h"
#include "gui/VisualComponents/clases/VisualClassComponentClase.h"
#include "gui/VisualComponents/clases/VisualClassComponentVia.h"
#include "model/clases/DiagramaClases.h"

ConversorDERaClases::ConversorDERaClases(WorkspaceDER *workspaceDERaConvertir, ConversorDERaClasesDelegate *delegate) {
	_workspaceDERaConvertir = workspaceDERaConvertir;
	_delegate = delegate;
	Diagram *diagramaDer = _workspaceDERaConvertir->getDiagram();
	DiagramaClases *nuevoDiagramaDeClases = new DiagramaClases(diagramaDer->getName() + "(convertido)");
	nuevoDiagramaDeClases->setPath(diagramaDer->getPath());
	_workspaceClasesConvertidoDesdeDER = new WorkspaceClases(nuevoDiagramaDeClases, true); // TODO es true?

	// opciones por default
	generarGettersYSetters = true;
}

void ConversorDERaClases::convertir() {
	// guardo los forks para el final, ya que precisan que todas las entidades ya hayan sido convertidos a clases
	std::vector<Component *> forksDelDiagramaDER;
	std::vector<Relation *> relacionesConConexionesPendientes;

	std::vector<Component *> *componentesDelDer = _workspaceDERaConvertir->getDiagram()->getComponents();
	for (unsigned int i= 0; i < componentesDelDer->size(); i++) {
		Component *componenteDelDer = componentesDelDer->at(i);

		if (componenteDelDer->getComponentType() == ComponentTypeDerEntity) {
			VisualComponentEntity *vistaDeLaEntidadAConvertir = dynamic_cast<VisualComponentEntity *>(_workspaceDERaConvertir->getVisualComponent(componenteDelDer));
			VisualClassComponentClase *vistaDeLaClaseALaQueSeConvirtioLaEntidad = this->convertirEntidad(vistaDeLaEntidadAConvertir);
			_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaClaseALaQueSeConvirtioLaEntidad);

			std::pair<Entity*, Clase *> claseParaEntidad;
			claseParaEntidad.first = dynamic_cast<Entity *>(vistaDeLaEntidadAConvertir->getDERComponent());
			claseParaEntidad.second = dynamic_cast<Clase *>(vistaDeLaClaseALaQueSeConvirtioLaEntidad->getClassesComponent());
			_mapeoClasesParaEntidades.insert(claseParaEntidad);
		}

		if (componenteDelDer->getComponentType() == ComponentTypeDerRelation) {
			VisualComponentRelation *vistaDeLaRelacionAConvertir = dynamic_cast<VisualComponentRelation *>(_workspaceDERaConvertir->getVisualComponent(componenteDelDer));
			Relation *relacion = dynamic_cast<Relation *>(vistaDeLaRelacionAConvertir->getComponent());

			bool seDebeConvertirRelacionAClasePorTenerAtributos = relacion->getRelationAttributes().size() > 0;
			bool seDebeConvertirRelacionAClasePorConectarMasDeDosEntidades = relacion->getLinkedEntities().size() > 2;

			if (seDebeConvertirRelacionAClasePorConectarMasDeDosEntidades || seDebeConvertirRelacionAClasePorTenerAtributos) {
				VisualClassComponentClase *vistaDeClaseConvertidaDeRelacion = this->convertirRelacionAClase(vistaDeLaRelacionAConvertir);
				_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeClaseConvertidaDeRelacion);
			}
			relacionesConConexionesPendientes.push_back(relacion);
		}

		if (componenteDelDer->getComponentType() == ComponentTypeDerFork) {
			forksDelDiagramaDER.push_back(componenteDelDer);
		}
	}

	// Ahora si puedo conectar los forks...
	for (unsigned int i = 0; i < forksDelDiagramaDER.size(); i++) {
		Component *forkDelDer = forksDelDiagramaDER[i];
		VisualComponentForkVia *vistaDelForkAConvertir = dynamic_cast<VisualComponentForkVia *>(_workspaceDERaConvertir->getVisualComponent(forkDelDer));
		Fork *fork = dynamic_cast<Fork *>(vistaDelForkAConvertir->getComponent());

		Entity *entidadPadre = fork->getPadre();
		Clase *clasePadre = _mapeoClasesParaEntidades[entidadPadre];
		VisualClassComponentClase *vistaDeLaClasePadre = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(clasePadre));

		for (unsigned int j = 0; j < fork->getHijos().size(); j++) {
			Entity *entidadHijo = fork->getHijos()[j];
			Clase *claseHijo = _mapeoClasesParaEntidades[entidadHijo];
			VisualClassComponentClase *vistaDeLaClaseHijo = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(claseHijo));

			std::cout << entidadHijo->getName() << std::endl;
			Connector *conectorDelPadreAlFork = fork->getConectorAlPadre();
			Connector *conectorDelHijoAlFork = fork->getConectoresALosHijos()[i];
			unsigned int idDeMapeoDelConectorDelHijo = conectorDelHijoAlFork ? conectorDelHijoAlFork->getIdParaMapeoDeConectores() : 0;
			unsigned int idDeMapeoDelConectorDelPadre = conectorDelPadreAlFork ? conectorDelPadreAlFork->getIdParaMapeoDeConectores() : 0;

			VisualComponentConector *vistaDelConectorDeLaClasePadre = vistaDeLaClasePadre->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDelPadre);
			VisualComponentConector *vistaDelConectorDeLaClaseHijo = vistaDeLaClaseHijo->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDelHijo);

			VisualClassComponentVia *vistaDeLaHerencia = new VisualClassComponentVia(vistaDelConectorDeLaClasePadre, getDiagramaClases(), vistaDelConectorDeLaClaseHijo);
			ViaClasses *herencia = dynamic_cast<ViaClasses *>(vistaDeLaHerencia->getComponent());

			herencia->tipoDeRelacionEntreClases = ViaClasses::TipoDeRelacionEntreClasesHerencia;

			vistaDelConectorDeLaClaseHijo->setVia(vistaDeLaHerencia);
			vistaDelConectorDeLaClasePadre->setVia(vistaDeLaHerencia);
			_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaHerencia);
		}
	}

	// ... y las relaciones entre clases también
	for (unsigned int i = 0; i < relacionesConConexionesPendientes.size(); i++) {
		Relation *relacionAConvertir = dynamic_cast<Relation *>(relacionesConConexionesPendientes[i]);

		std::vector<Entity *> entidadesConectadasALaRelacion;
		std::vector<Connector *> conectoresDeLasEntidadesALaRelacion;
		std::vector<Connector *> conectoresDeLaRelacionALasEntidades;
		for (unsigned int j = 0; j < relacionAConvertir->getLinkedEntities().size(); j++) {
			EntityRelationLinkInfo *infoDeLaEntidadRelacionada = relacionAConvertir->getLinkedEntities()[j];
			Entity *entidad = infoDeLaEntidadRelacionada->entity;
			Connector *conectorDeLaEntidad = infoDeLaEntidadRelacionada->conectorDeLaEntidad;
			Connector *conectorDeLaRelacion = infoDeLaEntidadRelacionada->conectorDeLaRelacion;
			entidadesConectadasALaRelacion.push_back(entidad);
			conectoresDeLasEntidadesALaRelacion.push_back(conectorDeLaEntidad);
			conectoresDeLaRelacionALasEntidades.push_back(conectorDeLaRelacion);
		}

		bool seCreoUnaClaseParaLaRelacion = _mapeoClasesParaRelaciones.find(relacionAConvertir) != _mapeoClasesParaRelaciones.end();
		if (!seCreoUnaClaseParaLaRelacion) { // entonces puedo conectar las clases que representan las entidades que une la relación directamente
			Entity *entidad1 = entidadesConectadasALaRelacion[0];
			Connector *conector1 = conectoresDeLasEntidadesALaRelacion[0];
			Clase *clase1 = _mapeoClasesParaEntidades[entidad1];
			VisualClassComponentClase *vistaDeLaClase1 = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(clase1));
			unsigned int idDeMapeoDelConectorDeLaEntidad1 = conector1 ? conector1->getIdParaMapeoDeConectores() : 0;
			VisualComponentConector *vistaDelConectorDeLaClase1 = vistaDeLaClase1->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDeLaEntidad1);

			Entity *entidad2 = entidadesConectadasALaRelacion[1];
			Connector *conector2 = conectoresDeLasEntidadesALaRelacion[1];
			Clase *clase2 = _mapeoClasesParaEntidades[entidad2];
			VisualClassComponentClase *vistaDeLaClase2 = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(clase2));
			unsigned int idDeMapeoDelConectorDeLaEntidad2 = conector2 ? conector2->getIdParaMapeoDeConectores() : 0;
			VisualComponentConector *vistaDelConectorDeLaClase2 = vistaDeLaClase2->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDeLaEntidad2);

			VisualClassComponentVia *vistaDeLaRelacion = new VisualClassComponentVia(vistaDelConectorDeLaClase1, getDiagramaClases(), vistaDelConectorDeLaClase2);
			ViaClasses *relacion = dynamic_cast<ViaClasses *>(vistaDeLaRelacion->getComponent());

			relacion->tipoDeRelacionEntreClases = ViaClasses::TipoDeRelacionEntreClasesAsociacion;

			vistaDelConectorDeLaClase1->setVia(vistaDeLaRelacion);
			vistaDelConectorDeLaClase2->setVia(vistaDeLaRelacion);
			_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaRelacion);
		} else {
			Clase *claseQueMapeaLaRelacion = _mapeoClasesParaRelaciones[relacionAConvertir];
			VisualClassComponentClase *vistaDeLaClaseQueMapeaLaRelacion = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(claseQueMapeaLaRelacion));

			for (unsigned int i = 0; i < entidadesConectadasALaRelacion.size(); i++) {
				Connector *conectorDeLaRelacionALaEntidad = conectoresDeLaRelacionALasEntidades[i];
				unsigned int idDeMapeoDelConectorDeLaRelacion = conectorDeLaRelacionALaEntidad ? conectorDeLaRelacionALaEntidad->getIdParaMapeoDeConectores() : 0;
				VisualComponentConector *vistaDelConectorDeLaClaseQueMapeaLaRelacion = vistaDeLaClaseQueMapeaLaRelacion->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDeLaRelacion);

				Entity *entidadConectadaALaRelacion = entidadesConectadasALaRelacion[i];
				Connector *conectorDeLaEntidadALaRelacion = conectoresDeLasEntidadesALaRelacion[1];
				Clase *claseQueMapeaLaEntidad = _mapeoClasesParaEntidades[entidadConectadaALaRelacion];
				VisualClassComponentClase *vistaDeLaClaseQueMapeaLaEntidad = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getClassesVisualComponent(claseQueMapeaLaEntidad));
				unsigned int idDeMapeoDelConectorDeLaEntidadALaRelacion = conectorDeLaEntidadALaRelacion ? conectorDeLaEntidadALaRelacion->getIdParaMapeoDeConectores() : 0;
				VisualComponentConector *vistaDelConectorDeLaClaseQueMapeaLaEntidad = vistaDeLaClaseQueMapeaLaEntidad->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDeLaEntidadALaRelacion);

				VisualClassComponentVia *vistaDeLaViaQueConecta = new VisualClassComponentVia(vistaDelConectorDeLaClaseQueMapeaLaRelacion, getDiagramaClases(), vistaDelConectorDeLaClaseQueMapeaLaEntidad);
				ViaClasses *viaQueConecta = dynamic_cast<ViaClasses *>(vistaDeLaViaQueConecta->getComponent());

				viaQueConecta->tipoDeRelacionEntreClases = ViaClasses::TipoDeRelacionEntreClasesAsociacion;

				vistaDelConectorDeLaClaseQueMapeaLaRelacion->setVia(vistaDeLaViaQueConecta);
				vistaDelConectorDeLaClaseQueMapeaLaEntidad->setVia(vistaDeLaViaQueConecta);
				_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaViaQueConecta);
			}
		}
	}

	_workspaceClasesConvertidoDesdeDER->necesitaReacomodar();

	_delegate->conversorDERaClasesTerminoConversion(_workspaceClasesConvertidoDesdeDER);
}

VisualClassComponentClase *ConversorDERaClases::convertirEntidad(VisualComponentEntity *vistaDeEntidad) {
	Entity *entidadAConvertir = dynamic_cast<Entity *>(vistaDeEntidad->getComponent());
	VisualClassComponentClase *nuevaVistaDeClase = new VisualClassComponentClase(_workspaceClasesConvertidoDesdeDER->getDiagram());
	Clase *claseDeLaNuevaVista = dynamic_cast<Clase*>(nuevaVistaDeClase->getComponent());

	nuevaVistaDeClase->setX(vistaDeEntidad->getX() * 2);
	nuevaVistaDeClase->setY(vistaDeEntidad->getY() * 2);
	claseDeLaNuevaVista->setName(entidadAConvertir->getName());

	std::vector<Attribute *> atributosDeLaEntidad = entidadAConvertir->getEntityAttributes();
	std::vector<Atributo *> atributosDeLaNuevaClase = this->convertirAtributos(atributosDeLaEntidad);
	for(unsigned int i = 0; i < atributosDeLaNuevaClase.size(); i++) {
		Atributo *nuevoAtributo = atributosDeLaNuevaClase[i];
		claseDeLaNuevaVista->addAtributo(nuevoAtributo);
	}

	std::vector<CompositeAttribute *> atributosCompuestosDeLaEntidad = entidadAConvertir->getEntityCompositeAttributes();
	std::vector<Atributo *> atributosCompuestosEnLaNuevaClase = this->convertirAtributosCompuestos(atributosCompuestosDeLaEntidad, entidadAConvertir, nuevaVistaDeClase);
	for(unsigned int i = 0; i < atributosCompuestosEnLaNuevaClase.size(); i++) {
		Atributo *nuevoAtributo = atributosCompuestosEnLaNuevaClase[i];
		claseDeLaNuevaVista->addAtributo(nuevoAtributo);
	}

	if (generarGettersYSetters) {
		this->generarGettersYSettersParaClase(claseDeLaNuevaVista);
	}

	return nuevaVistaDeClase;
}

VisualClassComponentClase *ConversorDERaClases::convertirRelacionAClase(VisualComponentRelation *vistaDeRelacion) {
	Relation *relacionAConvertir = dynamic_cast<Relation *>(vistaDeRelacion->getComponent());
	VisualClassComponentClase *nuevaVistaDeClase = new VisualClassComponentClase(_workspaceClasesConvertidoDesdeDER->getDiagram());
	Clase *claseDeLaNuevaVista = dynamic_cast<Clase *>(nuevaVistaDeClase->getComponent());

	nuevaVistaDeClase->setX(vistaDeRelacion->getX() * 2);
	nuevaVistaDeClase->setY(vistaDeRelacion->getY() * 2);
	claseDeLaNuevaVista->setName(relacionAConvertir->getName());

	_mapeoClasesParaRelaciones.insert(std::pair<Relation *, Clase *>(relacionAConvertir, claseDeLaNuevaVista));

	std::vector<Attribute *> atributosDeLaRelacion = relacionAConvertir->getRelationAttributes();
	bool tieneAtributos = atributosDeLaRelacion.size() > 0;

	if (tieneAtributos) {
		std::vector<Atributo *> atributosDeLaNuevaClase = this->convertirAtributos(atributosDeLaRelacion);
		for(unsigned int i = 0; i < atributosDeLaNuevaClase.size(); i++) {
			Atributo *nuevoAtributo = atributosDeLaNuevaClase[i];
			claseDeLaNuevaVista->addAtributo(nuevoAtributo);
		}

		std::vector<CompositeAttribute *> atributosCompuestosDeLaRelacion = relacionAConvertir->getRelationCompositeAttributes();
		std::vector<Atributo *> atributosCompuestosEnLaNuevaClase = this->convertirAtributosCompuestos(atributosCompuestosDeLaRelacion, relacionAConvertir, nuevaVistaDeClase);
		for(unsigned int i = 0; i < atributosCompuestosEnLaNuevaClase.size(); i++) {
			Atributo *nuevoAtributo = atributosDeLaNuevaClase[i];
			claseDeLaNuevaVista->addAtributo(nuevoAtributo);
		}

		if (generarGettersYSetters) {
			this->generarGettersYSettersParaClase(claseDeLaNuevaVista);
		}
	}

	return nuevaVistaDeClase;
}

std::vector<Atributo *> ConversorDERaClases::convertirAtributosCompuestos(std::vector<CompositeAttribute *> atributosCompuestosDelComponentDER, Entity *entidad, VisualClassComponentClase *vistaDeLaClaseQueRepresentaLaEntidad) {
	std::vector<Atributo *> atributosDeClase;
	for(unsigned int i = 0; i < atributosCompuestosDelComponentDER.size(); i++) {
		CompositeAttribute *atributoCompuestoDelComponenteDER = atributosCompuestosDelComponentDER[i];
		VisualClassComponentClase *nuevaVistaDeClaseDesdeAtributoCompuesto = this->convertirAtributoCompuesto(atributoCompuestoDelComponenteDER);
		_workspaceClasesConvertidoDesdeDER->addVisualComponent(nuevaVistaDeClaseDesdeAtributoCompuesto);

		Connector *conectorDeLaEntidadAlAtributoCompuesto = entidad->getConnectorToAttribute(atributoCompuestoDelComponenteDER);
		unsigned int idDeMapeoDelConectorDeLaEntidadConectadaAlAtributoCompuesto = conectorDeLaEntidadAlAtributoCompuesto ? conectorDeLaEntidadAlAtributoCompuesto->getIdParaMapeoDeConectores() : 0;
		std::cout << "idDeMapeoDelConectorDeLaEntidadConectadaAlAtributoCompuesto " << idDeMapeoDelConectorDeLaEntidadConectadaAlAtributoCompuesto << std::endl;
		VisualComponentConector *vistaDelConectorDeLaEntidadAlAtributoCompuesto = vistaDeLaClaseQueRepresentaLaEntidad->getConectorParaIdDeMapeoDeEntidad(idDeMapeoDelConectorDeLaEntidadConectadaAlAtributoCompuesto);
		VisualComponentConector *vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto = nuevaVistaDeClaseDesdeAtributoCompuesto->getConectorLibre();

		VisualClassComponentVia *vistaDeLaRelacionEntreClases = new VisualClassComponentVia(vistaDelConectorDeLaEntidadAlAtributoCompuesto, getDiagramaClases(), vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto);
		ViaClasses *relacion = dynamic_cast<ViaClasses *>(vistaDeLaRelacionEntreClases->getComponent());

		relacion->tipoDeRelacionEntreClases = ViaClasses::TipoDeRelacionEntreClasesAsociacion;

		vistaDelConectorDeLaEntidadAlAtributoCompuesto->setVia(vistaDeLaRelacionEntreClases);
		vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto->setVia(vistaDeLaRelacionEntreClases);
		_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaRelacionEntreClases);

		Atributo *atributoDeClaseReferenteAlAtributoCompuesto = new Atributo(
				nuevaVistaDeClaseDesdeAtributoCompuesto->getComponent()->getName(),
				PRIVATE,
				atributoCompuestoDelComponenteDER->getName(),
				false);
		atributosDeClase.push_back(atributoDeClaseReferenteAlAtributoCompuesto);
	}
	return atributosDeClase;
}

std::vector<Atributo *> ConversorDERaClases::convertirAtributosCompuestos(std::vector<CompositeAttribute *> atributosCompuestosDelComponentDER, Relation *relacion, VisualClassComponentClase *vistaDeLaClaseQueRepresentaLaRelacion) {
	std::vector<Atributo *> atributosDeClase;
	for(unsigned int i = 0; i < atributosCompuestosDelComponentDER.size(); i++) {
		CompositeAttribute *atributoCompuestoDelComponenteDER = atributosCompuestosDelComponentDER[i];
		VisualClassComponentClase *nuevaVistaDeClaseDesdeAtributoCompuesto = this->convertirAtributoCompuesto(atributoCompuestoDelComponenteDER);
		_workspaceClasesConvertidoDesdeDER->addVisualComponent(nuevaVistaDeClaseDesdeAtributoCompuesto);

//		Connector *conectorDeLaEntidadAlAtributoCompuesto = relacion->getConnectorToAttribute(atributoCompuestoDelComponenteDER);
//		Clase *claseDeLaEntidad = _mapeoClasesParaRelaciones[relacion];
//		VisualClassComponentClase *vistaDeLaClase = dynamic_cast<VisualClassComponentClase *>(_workspaceClasesConvertidoDesdeDER->getVisualComponent(claseDeLaEntidad));

//		unsigned int idDeMapeoDelConectorDeLaEntidadConectadaAlAtributoCompuesto = conectorDeLaRelacionAlAtributoCompuesto ? conectorDeLaRelacionAlAtributoCompuesto->getIdParaMapeoDeConectores() : 0;
		VisualComponentConector *vistaDelConectorDeLaRelacionAlAtributoCompuesto = vistaDeLaClaseQueRepresentaLaRelacion->getConectorLibre();

		VisualComponentConector *vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto = nuevaVistaDeClaseDesdeAtributoCompuesto->getConectorLibre();

		VisualClassComponentVia *vistaDeLaRelacionEntreClases = new VisualClassComponentVia(vistaDelConectorDeLaRelacionAlAtributoCompuesto, getDiagramaClases(), vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto);
		ViaClasses *relacion = dynamic_cast<ViaClasses *>(vistaDeLaRelacionEntreClases->getComponent());

		relacion->tipoDeRelacionEntreClases = ViaClasses::TipoDeRelacionEntreClasesAsociacion;

		vistaDelConectorDeLaRelacionAlAtributoCompuesto->setVia(vistaDeLaRelacionEntreClases);
		vistaDelConectorDeLaClaseQueRepresentaAlAtributoCompuesto->setVia(vistaDeLaRelacionEntreClases);
		_workspaceClasesConvertidoDesdeDER->addVisualComponent(vistaDeLaRelacionEntreClases);

		Atributo *atributoDeClaseReferenteAlAtributoCompuesto = new Atributo(
				nuevaVistaDeClaseDesdeAtributoCompuesto->getComponent()->getName(),
				PRIVATE,
				atributoCompuestoDelComponenteDER->getName(),
				false);
		atributosDeClase.push_back(atributoDeClaseReferenteAlAtributoCompuesto);
	}
	return atributosDeClase;
}

std::vector<Atributo *> ConversorDERaClases::convertirAtributos(std::vector<Attribute *> atributosDelComponentDER) {
	std::vector<Atributo *> atributosDeClase;
	for(unsigned int i = 0; i < atributosDelComponentDER.size(); i++) {
		Attribute *atributoDelComponentDER = atributosDelComponentDER[i];
		Atributo *nuevoAtributoDeClase = this->convertirAtributo(atributoDelComponentDER, "tipo");
		atributosDeClase.push_back(nuevoAtributoDeClase);
	}
	return atributosDeClase;
}

Atributo *ConversorDERaClases::convertirAtributo(Attribute *atributo, std::string tipoDeDato) {
	std::string tipoDeDatoDelAtributo = tipoDeDato;
	Visibilidad visibilidadDelAtributo = PRIVATE;
	std::string nombreDelAtributo = atributo->getName();
	bool atributoEsEstatico = false;
	Atributo *nuevoAtributo = new Atributo(
			tipoDeDatoDelAtributo,
			visibilidadDelAtributo,
			nombreDelAtributo,
			atributoEsEstatico);
	return nuevoAtributo;
}

VisualClassComponentClase *ConversorDERaClases::convertirAtributoCompuesto(CompositeAttribute *atributoCompuesto) {
	VisualClassComponentClase *nuevaVistaDeClase = new VisualClassComponentClase(_workspaceClasesConvertidoDesdeDER->getDiagram());
	Clase *claseDeLaNuevaVista = dynamic_cast<Clase *>(nuevaVistaDeClase->getComponent());

	nuevaVistaDeClase->setX(atributoCompuesto->getX() * 3);
	nuevaVistaDeClase->setY(atributoCompuesto->getY() * 3);
	std::string nombreDeLaClase = atributoCompuesto->getName();
	nombreDeLaClase[0] = toupper(nombreDeLaClase[0]);
	claseDeLaNuevaVista->setName(nombreDeLaClase);

	std::vector<Attribute *> atributosComponentesDelCompuesto = atributoCompuesto->getInnerAttributes();
	for(unsigned int i = 0; i < atributosComponentesDelCompuesto.size(); i++) {
		Attribute *atributoComponenteDelCompuesto = atributosComponentesDelCompuesto[i];
		Atributo *nuevoAtributo = this->convertirAtributo(atributoComponenteDelCompuesto, "tipo");
		claseDeLaNuevaVista->addAtributo(nuevoAtributo);
	}

	if (generarGettersYSetters) {
		this->generarGettersYSettersParaClase(claseDeLaNuevaVista);
	}

	return nuevaVistaDeClase;
}

Metodo *ConversorDERaClases::generarGetterParaAtributo(Atributo *atributo) {
	std::string tipoDeDatoDevuelto = "";//atributo->getTipoDato()->getNombre();

	Visibilidad visibilidad = PUBLIC;
	std::string nombreDelGetter = "get" + atributo->getNombre();
	nombreDelGetter[3] = toupper(nombreDelGetter[3]);

	Metodo *getter = new Metodo(tipoDeDatoDevuelto, visibilidad, nombreDelGetter);
	return getter;
}

Metodo *ConversorDERaClases::generarSetterParaAtributo(Atributo *atributo) {
	std::string tipoDeDatoDevuelto = "";
	Parametro *parametro = new Parametro(atributo->getTipoDato(), atributo->getNombre());
	Visibilidad visibilidad = PUBLIC;
	std::string nombreDelGetter = "set" + atributo->getNombre();
	nombreDelGetter[3] = toupper(nombreDelGetter[3]);

	Metodo *setter = new Metodo(tipoDeDatoDevuelto, visibilidad, nombreDelGetter);
	setter->agregarParametro(parametro);
	return setter;
}

void ConversorDERaClases::generarGettersYSettersParaClase(Clase *clase) {
	for(unsigned int i = 0; i < clase->getAtributos().size(); i++) {
		Atributo *atributoDeLaNuevaClase = clase->getAtributos()[i];

		Metodo *getter = generarGetterParaAtributo(atributoDeLaNuevaClase);
		clase->addMetodo(getter);

		Metodo *setter = generarSetterParaAtributo(atributoDeLaNuevaClase);
		clase->addMetodo(setter);
	}
}

ConversorDERaClases::~ConversorDERaClases() {
	// TODO Auto-generated destructor stub
}
